#ifndef DATA_CONTROLLER_H
#define DATA_CONTROLLER_H

#include <memory>
#include <string>

#include "common/elements/element_container.hpp"
#include "common/elements/element_type.hpp"

#include "database/data_elements/data_element.h"
#include "database/data_elements/data_role.h"
#include "database/data_elements/data_team.h"
#include "database/data_elements/data_user.h"
#include "database/data_elements/data_user_team_role.h"

#include "database/data_gate.h"

class DataController final : public Database::DataGate
{
public:
    DataController();

    bool loadPermanentElements();

    std::vector<unsigned> ids(Elements::ElementType elementType) const;

    Database::DataElements elements(
        Elements::ElementType elementType,
        const std::vector<unsigned> ids = {}
    ) const;
    Database::DataElementPtr element(
        Elements::ElementType elementType,
        unsigned id
    ) const;

    void save(Elements::ElementPtr element);
    void save(Database::DataElementPtr element);
    void save(const Database::DataElements& elements);

    void remove(Elements::ElementType type, const std::vector<unsigned>& ids);
    void remove(Elements::ElementType type, unsigned id);

    std::vector<std::shared_ptr<Database::DataUser>> users() const;
    std::shared_ptr<Database::DataUser> user(unsigned id) const;
    std::shared_ptr<Database::DataUser> userByLogin(const std::string& userLogin) const;

    std::vector<std::shared_ptr<Database::DataTeam>> teams() const;
    std::shared_ptr<Database::DataTeam> team(unsigned id) const;

    std::vector<std::shared_ptr<Database::DataRole>> roles() const;
    std::shared_ptr<Database::DataRole> role(unsigned id) const;

private:
    Elements::ElementContainer<Database::DataUser> m_users;
    Elements::ElementContainer<Database::DataTeam> m_teams;
    Elements::ElementContainer<Database::DataRole> m_roles;
    Elements::ElementContainer<Database::DataUserTeamRole> m_userTeamRoles;
};

#endif // DATA_CONTROLLER_H
